import { readFileSync, writeFileSync } from 'node:fs'
import { join, relative } from 'node:path/posix'
import { PROJECT_ROOT } from './utils/PROJECT_ROOT.ts'
import { findFilesByName } from './utils/findFilesByName.ts'

const TARGET_PROTOCOL = 'workspace:^'
const FIX = process.argv.includes('--fix')

const packageJsonPaths = [
  ...findFilesByName({
    name: 'package.json',
    cwd: join(PROJECT_ROOT, 'packages'),
  }),
  ...findFilesByName({
    name: 'package.json',
    cwd: join(PROJECT_ROOT, 'apps'),
  }),
]

let hasIssues = false
const issues: Array<{ path: string; field: string; current: string; expected: string }> = []

for (const packageJsonPath of packageJsonPaths) {
  const content = readFileSync(packageJsonPath, 'utf-8')
  const packageJson = JSON.parse(content)
  const relativePath = relative(PROJECT_ROOT, packageJsonPath)

  // Check dependencies
  if (packageJson.dependencies) {
    for (const [depName, depVersion] of Object.entries(packageJson.dependencies)) {
      if (typeof depVersion === 'string' && depVersion.startsWith('workspace:')) {
        if (depVersion !== TARGET_PROTOCOL) {
          hasIssues = true
          issues.push({
            path: relativePath,
            field: `dependencies.${depName}`,
            current: depVersion,
            expected: TARGET_PROTOCOL,
          })

          if (FIX) {
            packageJson.dependencies[depName] = TARGET_PROTOCOL
          }
        }
      }
    }
  }

  // Check devDependencies
  if (packageJson.devDependencies) {
    for (const [depName, depVersion] of Object.entries(packageJson.devDependencies)) {
      if (typeof depVersion === 'string' && depVersion.startsWith('workspace:')) {
        if (depVersion !== TARGET_PROTOCOL) {
          hasIssues = true
          issues.push({
            path: relativePath,
            field: `devDependencies.${depName}`,
            current: depVersion,
            expected: TARGET_PROTOCOL,
          })

          if (FIX) {
            packageJson.devDependencies[depName] = TARGET_PROTOCOL
          }
        }
      }
    }
  }

  // Write back if fixed
  if (FIX) {
    const hasChanges = issues.some((issue) => issue.path === relativePath)
    if (hasChanges) {
      writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, 'utf-8')
    }
  }
}

if (hasIssues) {
  if (FIX) {
    console.log('✅ Fixed workspace protocol in the following packages:')
    issues.forEach((issue) => {
      console.log(`  ${issue.path}: ${issue.field}`)
      console.log(`    ${issue.current} → ${issue.expected}`)
    })
  } else {
    console.error('❌ Found packages using incorrect workspace protocol:')
    issues.forEach((issue) => {
      console.error(`  ${issue.path}: ${issue.field}`)
      console.error(`    Current: ${issue.current}`)
      console.error(`    Expected: ${issue.expected}`)
    })
    console.error('\n💡 Run with --fix to automatically fix these issues:')
    console.error('   pnpm check:workspace-protocol --fix')
    process.exit(1)
  }
} else {
  console.log('✅ All workspace dependencies use workspace:^ protocol')
}
